home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / xnot12a.zip / XKEY.C < prev    next >
C/C++ Source or Header  |  1993-06-12  |  13KB  |  639 lines

  1. #ifdef X11
  2.   
  3. #include "jam.h"
  4. #include "def.h"
  5. #include "keyname.h"
  6. #include "ttydef.h"
  7. #include "chrdef.h"
  8.  
  9. #include "keysym.h"
  10. #ifdef HP
  11. # include "HPkeysym.h"
  12. #endif
  13.   
  14. #define MAXCHARS 512
  15. static KCHAR *kbdinput = 0;
  16. static KCHAR *putback_kbdinput = 0;
  17. static int kbdcount = 0;
  18. static int putback_kbdcount = 0;
  19.  
  20. static BOOL s_IgnoreWM_CHAR = FALSE; 
  21.  
  22. /* Needed by all sorts of things
  23. */
  24. static BOOL bCapLock = FALSE;
  25. static int bShifted = 0;
  26. static int bCtrled = 0;
  27. static int bAlted = 0;
  28.  
  29. /* map subfunctions
  30. */
  31. static BOOL rn_(mapFkey, (KeySym *pk, BOOL shift, BOOL ctrl, BOOL alt));
  32. static BOOL rn_(mapKPkey, (KeySym *pk));
  33. static BOOL rn_(mapAlphaKey, (KeySym *pk, BOOL shift, BOOL ctrl, BOOL alt, 
  34.                               XKeyEvent *e));
  35.  
  36. /* alloc the internal event queues
  37. */
  38. void InitInput()
  39. {
  40.  if (!(kbdinput = (KCHAR *)calloc(MAXCHARS, sizeof(KCHAR))))
  41.    WindowMessage("Unable to init kbdinput", TRUE);
  42.  if (!(putback_kbdinput = (KCHAR *)calloc(MAXCHARS, sizeof(KCHAR))))
  43.    WindowMessage("Unable to init putback_kbdinput", TRUE);
  44. }
  45.  
  46. /* putback kchar to to input queue
  47.  */
  48. void PutbackKchar(c)
  49. KCHAR c;
  50. {
  51.   if (putback_kbdcount < MAXCHARS)
  52.     {
  53.       putback_kbdinput[putback_kbdcount] = c;
  54.       putback_kbdcount++;
  55.     }
  56. }
  57.  
  58. /* if putback'ed events, push to normal input stream now
  59. */
  60. void CheckForPutback()
  61. {
  62.   int i, j;
  63.  
  64.   /* if not enough room, die
  65.   */
  66.   if ((MAXCHARS - kbdcount) < putback_kbdcount)
  67.     putback_kbdcount = 0;
  68.   else
  69.     for (j = putback_kbdcount, i = 0; i < j; i++)
  70.        {
  71.          AddKchar(putback_kbdinput[i]);
  72.          putback_kbdcount--;
  73.        }
  74. }
  75.  
  76. /* push normal string to input buf
  77.  */
  78. void AddString(s)
  79. char *s;
  80. {
  81.   while (s && *s)
  82.     AddKchar((KCHAR)*s++);
  83. }
  84.  
  85. /* add kchar to internal queue of collected/manufactured events
  86.  */
  87. void AddKchar(c)
  88. KCHAR c;
  89. {
  90.   if (kbdcount < MAXCHARS)
  91.     {
  92.       kbdinput[kbdcount] = c;
  93.       kbdcount++;
  94.     }
  95.   else
  96.     ttbeep();
  97. }
  98.  
  99. /* Get shift state of event; is mouse or keyboard or error!
  100. */
  101. BOOL GetShiftState(e)
  102. XEvent *e;
  103. {
  104.    XKeyEvent *event = (XKeyEvent *)e;
  105.  
  106.    return((event->state & ShiftMask) || (event->state & LockMask));
  107. }
  108. /* Get ctrl state of event; is mouse or keyboard or error!
  109. */
  110. BOOL GetCtrlState(e)
  111. XEvent *e;
  112. {
  113.    XKeyEvent *event = (XKeyEvent *)e;
  114.  
  115.    return(event->state & ControlMask);
  116. }
  117.  
  118. /* return first inqueued char from event into
  119.  * pkchar (if NON_NULL) and return status
  120.  */
  121. BOOL WindowReturnKCHAR(pkchar)
  122. KCHAR *pkchar;
  123. {
  124.   register int i;
  125.   BOOL result = FALSE;
  126.   
  127.   /* if something, remove from queue head 
  128.    * and push the queue down
  129.    * (should use head/tail pointers!)
  130.    */
  131.   if (kbdcount > 0)
  132.     {
  133.       result = TRUE;
  134.       if (pkchar)
  135.     {
  136.       *pkchar = kbdinput[0];
  137.       kbdcount--;
  138.       for (i = 0; i < kbdcount; i++)
  139.         kbdinput[i] = kbdinput[i+1];
  140.     }
  141.     }
  142.   return(result);
  143. }
  144.  
  145. /* map windows event to kchar
  146.  */
  147. BOOL WindowMapKey(event, down)
  148. XKeyEvent *event;
  149. BOOL down;
  150. {
  151.   KeySym key;
  152.   KCHAR wKey;
  153.   BOOL mapped;
  154.   char unknown[NLINE * 2];
  155.   
  156.   key = XLookupKeysym(event, 0);
  157.   wKey = 0;
  158.   mapped = FALSE;
  159.  
  160. #ifdef Xlib_loses_keys
  161.   if ((key == XK_Shift_L) || (key == XK_Shift_R) ||
  162.       (key == XK_Caps_Lock) ||
  163.       (key == XK_Control_L) || (key == XK_Control_R) ||
  164.       (key == XK_Escape) || (key == XK_Meta_L) || (key == XK_Meta_R) ||
  165.       (key == XK_Alt_L) || (key == XK_Alt_R) || (key == XK_Multi_key))
  166.     {
  167.       if (down)
  168.         printf("\nNew state on 'down'\n");
  169.       GetKeyStates();        /* recompute all values */
  170.       return(FALSE);
  171.     }
  172.   else
  173. #else
  174.    bShifted = (event->state & ShiftMask) || (event->state & LockMask);
  175.    bCtrled = event->state & ControlMask;
  176.    bAlted = (event->state & Mod1Mask) || (event->state & Mod2Mask) ||
  177.             (event->state & Mod3Mask) || (event->state & Mod4Mask) ||
  178.             (event->state & Mod5Mask);
  179. #endif 
  180.  
  181. #ifdef DEBUGKEYS
  182.     printf("keycode %d [%s]\n", event->keycode, XKeysymToString(key));
  183. #endif
  184.  
  185.     if (!down)
  186.       return(FALSE);    /* ignore other up events */
  187.  
  188.   /* grab some keys up front
  189.    */
  190.   switch (key)
  191.     {
  192.   case XK_space:    /* really printable, but caught up here */
  193.     if (bCtrled)
  194.       {   
  195.         ExtendedFunction(function_name(setmark));
  196.         return (TRUE);
  197.       }
  198.     else
  199.       wKey = ' ';
  200.     break;
  201.  
  202. #ifdef HP
  203.   case XK_DeleteLine:
  204.     bCtrled = TRUE;        /* force it */
  205. #endif
  206.   case XK_BackSpace:
  207.     if (bCtrled)    /* hack to move to 0, kill whole line */
  208.       {
  209.         ExtendedFunction(function_name(gotobol));
  210.         ExtendedFunction(function_name(killline));
  211.         ExtendedFunction(function_name(killline));
  212.         return(TRUE);
  213.       }
  214.     else if (bShifted)
  215.       {
  216.          ExtendedFunction(function_name(delbword));
  217.          return(TRUE);
  218.       }
  219.     else
  220.       wKey = 0x7f;   /* ttyio mapped it this way too, ick ! */
  221.     break;
  222.  
  223.   case XK_Delete:
  224.     wKey = 0x7f;
  225.     break;
  226. #ifdef HP
  227.   case XK_DeleteChar:
  228.     wKey = KDELETE;
  229.     break;
  230. #endif
  231.  
  232.   case XK_Tab:
  233.     if (bShifted || bAlted)
  234.       {   
  235.         ExtendedFunction(function_name(hardtab));
  236.         return(TRUE);
  237.       }
  238.     wKey = CCHR('I');
  239.     break;
  240.  
  241.   case XK_Linefeed:
  242.     wKey = CCHR('N');
  243.     break;
  244.  
  245.   case XK_Return:
  246.     wKey = CCHR('M');
  247.     break;
  248.  
  249.   case XK_Escape:    /* should we keep this?? */
  250.     return (FALSE);
  251.  
  252.   case XK_Home:
  253.     if (bCtrled)
  254.       wKey = KCHOME;
  255.     else
  256.       wKey = KHOME;
  257.     break;
  258.  
  259.   case XK_Left:
  260.     if (bCtrled)
  261.       wKey = KCLEFT;
  262.     else
  263.       wKey = KLEFT;
  264.     break;
  265.  
  266.   case XK_Up:
  267.     if (bCtrled)
  268.       {
  269.         if (bAlted)
  270.           ExtendedFunction(function_name(prevwind));
  271.         else
  272.           ExtendedFunction(function_name(back1page));
  273.     return(TRUE);
  274.       }
  275.     else
  276.       wKey = KUP;
  277.     break;
  278.  
  279.   case XK_Right:
  280.     if (bCtrled)
  281.       wKey = KCRIGHT;
  282.     else
  283.       wKey = KRIGHT;
  284.     break;
  285.  
  286.   case XK_Down:
  287.     if (bCtrled)
  288.       {
  289.         if (bAlted)
  290.            ExtendedFunction(function_name(nextwind));
  291.         else
  292.            ExtendedFunction(function_name(forw1page));
  293.         return (TRUE);
  294.       }
  295.     else 
  296.       wKey = KDOWN;
  297.     break;
  298.  
  299.   case XK_Prior:
  300.     if (bCtrled)
  301.       wKey = KCPGUP;
  302.     else
  303.       wKey = KPGUP;
  304.     break;
  305.  
  306.   case XK_Next:
  307.     if (bCtrled)
  308.       wKey = KCPGDN;
  309.     else
  310.       wKey = KPGDN;
  311.     break;
  312.  
  313.   case XK_End:
  314.     if (bCtrled)
  315.       wKey = KCEND;
  316.     else
  317.       wKey = KEND;
  318.     break;
  319.  
  320.   case XK_Select:
  321.     if (bShifted)
  322.       wKey = KSSELECT;
  323.     else
  324.       wKey = KSELECT;
  325.     break;
  326.  
  327.   case XK_Find:
  328.     if (bShifted)
  329.       wKey = KSFIND;
  330.     else
  331.       wKey = KFIND;
  332.     break;
  333.  
  334.   case XK_Insert:
  335.     wKey = KINSERT;
  336.     break;
  337.  
  338.   default:   /* wasn't handled yet, try below */
  339.     break;
  340.     }
  341.  
  342.   /* if key was successfully mapped above, load to input queue
  343.   * and return
  344.   */
  345.   if (wKey != 0)
  346.     {
  347.       AddKchar(wKey);
  348.       return (TRUE);
  349.     }
  350.  
  351.   /* try mapping alphanumeric or special keys
  352.    */
  353.   if ((key >= XK_space) && (key <= XK_asciitilde))
  354.       mapped = mapAlphaKey(&key, bShifted, bCtrled, bAlted, event);
  355.   
  356.   else if ((key >= XK_F1) && (key <= XK_F12))
  357.       mapped = mapFkey(&key, bShifted, bCtrled, bAlted);
  358.  
  359.   else if ((key >= XK_KP_Enter) && (key <= XK_KP_9))
  360.       mapped = mapKPkey(&key);
  361.  
  362.   if (mapped)
  363.     {
  364.       wKey = (KCHAR)key;
  365.       AddKchar(wKey);
  366.       return (TRUE);
  367.      }
  368.  
  369.   /* unsupported key/message combination
  370.    */
  371.   if ((key == XK_Shift_L) || (key == XK_Shift_R) ||
  372.       (key == XK_Caps_Lock) ||
  373.       (key == XK_Control_L) || (key == XK_Control_R) ||
  374.       (key == XK_Escape) || (key == XK_Meta_L) || (key == XK_Meta_R) ||
  375.       (key == XK_Alt_L) || (key == XK_Alt_R) || (key == XK_Multi_key))
  376.     ;
  377.   else
  378.     {
  379.       sprintf(unknown, "Unknown key %x", key);
  380.       ewprintf(unknown);
  381.     }
  382.   return (FALSE);
  383. }
  384. /* function key mapping
  385. */
  386. static BOOL mapFkey(pwKey, bShifted, bCtrled, bAlted)
  387. KeySym *pwKey;
  388. BOOL bShifted;
  389. BOOL bCtrled;
  390. BOOL bAlted;
  391. {
  392.   KeySym wKey = *pwKey;
  393.   BOOL mapped = TRUE;
  394.  
  395.   switch(wKey)
  396.     {
  397.   case XK_F1:
  398.     if (bShifted && bCtrled) wKey = KCSF1;
  399.     else if (bShifted) wKey = KSF1;
  400.     else if (bCtrled) wKey = KCF1;
  401.     else if (bAlted) wKey = KMF1;
  402.     else wKey = KF1;
  403.     break;
  404.       
  405.   case XK_F2:
  406.     if (bShifted && bCtrled) wKey = KCSF2;
  407.     else if (bShifted) wKey = KSF2;
  408.     else if (bCtrled) wKey = KCF2;
  409.     else if (bAlted) wKey = KMF2;
  410.     else wKey = KF2;
  411.     break;
  412.       
  413.   case XK_F3:
  414.     if (bShifted && bCtrled) wKey = KCSF3;
  415.     else if (bShifted) wKey = KSF3;
  416.     else if (bCtrled) wKey = KCF3;
  417.     else if (bAlted) wKey = KMF3;
  418.     else wKey = KF3;
  419.     break;
  420.       
  421.   case XK_F4:
  422.     if (bShifted && bCtrled) wKey = KCSF4;
  423.     else if (bShifted) wKey = KSF4;
  424.     else if (bCtrled) wKey = KCF4;
  425.     else if (bAlted) wKey = KMF4;
  426.     else wKey = KF4;
  427.     break;
  428.       
  429.   case XK_F5:
  430.     if (bShifted && bCtrled) wKey = KCSF5;
  431.     else if (bShifted) wKey = KSF5;
  432.     else if (bCtrled) wKey = KCF5;
  433.     else if (bAlted) wKey = KMF5;
  434.     else wKey = KF5;
  435.     break;
  436.       
  437.   case XK_F6:
  438.     if (bShifted && bCtrled) wKey = KCSF6;
  439.     else if (bShifted) wKey = KSF6;
  440.     else if (bCtrled) wKey = KCF6;
  441.     else if (bAlted) wKey = KMF6;
  442.     else wKey = KF6;
  443.     break;
  444.       
  445.   case XK_F7:
  446.     if (bShifted && bCtrled) wKey = KCSF7;
  447.     else if (bShifted) wKey = KSF7;
  448.     else if (bCtrled) wKey = KCF7;
  449.     else if (bAlted) wKey = KMF7;
  450.     else wKey = KF7;
  451.     break;
  452.       
  453.   case XK_F8:
  454.     if (bShifted && bCtrled) wKey = KCSF8;
  455.     else if (bShifted) wKey = KSF8;
  456.     else if (bCtrled) wKey = KCF8;
  457.     else if (bAlted) wKey = KMF8;
  458.     else wKey = KF8;
  459.     break;
  460.       
  461.   case XK_F9:
  462.     if (bShifted && bCtrled) wKey = KCSF9;
  463.     else if (bShifted) wKey = KSF9;
  464.     else if (bCtrled) wKey = KCF9;
  465.     else if (bAlted) wKey = KMF9;
  466.     else wKey = KF9;
  467.     break;
  468.   
  469.   case XK_F10:
  470.     if (bShifted && bCtrled) wKey = KCSF10;
  471.     else if (bShifted) wKey = KSF10;
  472.     else if (bCtrled) wKey = KCF10;
  473.     else if (bAlted) wKey = KMF10;
  474.     else wKey = KF10;
  475.     break;
  476.  
  477.   case XK_F11:
  478.     if (bShifted && bCtrled) wKey = KCSF11;
  479.     else if (bShifted) wKey = KSF11;
  480.     else if (bCtrled) wKey = KCF11;
  481.     else if (bAlted) wKey = KMF11;
  482.     else wKey = KF11;
  483.     break;
  484.  
  485.   case XK_F12:
  486.     if (bShifted && bCtrled) wKey = KCSF12;
  487.     else if (bShifted) wKey = KSF12;
  488.     else if (bCtrled) wKey = KCF12;
  489.     else if (bAlted) wKey = KMF12;
  490.     else wKey = KF12;
  491.     break;
  492.  
  493.   default:
  494.     mapped = FALSE;
  495.     }
  496.  
  497.   *pwKey = wKey;
  498.   return (mapped);
  499. }
  500. /* keypadkey mapping
  501. */
  502. static BOOL mapKPkey(pwKey)
  503. KeySym *pwKey;
  504. {
  505.   KeySym wKey = *pwKey;
  506.   BOOL mapped = TRUE;
  507.    
  508.   switch(wKey)
  509.     {
  510.   case XK_KP_0:
  511.     wKey = KP0;
  512.     break;
  513.  
  514.   case XK_KP_1:
  515.     wKey = KP1;
  516.     break;
  517.  
  518.   case XK_KP_2:
  519.     wKey = KP2;
  520.     break;
  521.  
  522.   case XK_KP_3:
  523.     wKey = KP3;
  524.     break;
  525.  
  526.   case XK_KP_4:
  527.     wKey = KP4;
  528.     break;
  529.  
  530.   case XK_KP_5:
  531.     wKey = KP5;
  532.     break;
  533.  
  534.   case XK_KP_6:
  535.     wKey = KP6;
  536.     break;
  537.  
  538.   case XK_KP_7:
  539.     wKey = KP7;
  540.     break;
  541.  
  542.   case XK_KP_8:
  543.     wKey = KP8;
  544.     break;
  545.  
  546.   case XK_KP_9:
  547.     wKey = KP9;
  548.     break;
  549.  
  550.   case XK_KP_Add:
  551.     wKey = KPADD;
  552.     break;
  553.  
  554.   case XK_KP_Multiply:
  555.     wKey = KPMUL;
  556.     break;
  557.  
  558.   case XK_KP_Subtract:
  559.     wKey = KPSUB;
  560.     break;
  561.  
  562.   case XK_KP_Decimal:
  563.     wKey = KPDEL;
  564.     break;
  565.  
  566.   case XK_KP_Divide:
  567.     wKey = KPDIV;
  568.     break;
  569.  
  570.   case XK_KP_Enter:
  571.     wKey = KPENTER;
  572.     break;
  573.  
  574.   default:
  575.     mapped = FALSE;
  576.     }
  577.  
  578.   *pwKey = wKey;
  579.   s_IgnoreWM_CHAR = mapped;    /* generated an event to ignore */
  580.   return (mapped);
  581. }
  582. static BOOL mapAlphaKey(pKey, bShifted, bCtrled, bAlted, event)
  583. KeySym *pKey;
  584. BOOL bShifted;
  585. BOOL bCtrled;
  586. BOOL bAlted;
  587. XKeyEvent *event;
  588. {
  589. #define LEN 10
  590.   char buffer[LEN];
  591.   KCHAR wkey;
  592.   int count;
  593.  
  594.   /* strip junk
  595.   */
  596.   wkey = (KCHAR)(*pKey & 0xFF);
  597.  
  598.   /* some modifier keys need to be uppercased (this
  599.   * captures normal translated events which would normally be in
  600.   * in the buffer)
  601.   */
  602.   if (bAlted || bCtrled || bShifted)
  603.     {
  604.       if ((wkey >= 'a') && (wkey <= 'z'))
  605.     {
  606.       wkey = TOUPPER(wkey);            /* defensive.... */
  607.  
  608.       /* Ctrl overrides Alt, Alt overrides Shift... no multiple
  609.        * modifiers at this level. Note that Shift already took effect
  610.        * above anyway
  611.        */
  612.       wkey = (bCtrled ? CCHR(wkey) : (bAlted ? (wkey | METABIT) : wkey));
  613.     }
  614.       else if ((wkey >= '0') && (wkey <= '9') && !bShifted)
  615.        {
  616.      wkey = (bAlted ? (wkey | METABIT) : wkey);
  617.        }
  618.  
  619.       /* must be special char
  620.        */
  621.       else if (bShifted)
  622.     {
  623.       KeySym newkey;
  624.       char buffer[10];
  625.  
  626.       if (XLookupString(event, buffer, 10, &newkey, 0) != NoSymbol)
  627.             {  
  628.           wkey = buffer[0];
  629.             }
  630.       else
  631.         return (FALSE);      /* ack! */
  632.     }
  633.     }
  634.  
  635.   *pKey = (KeySym)wkey;    /* return value */
  636.   return (TRUE);        /* should be impossible to fail */
  637. }
  638. #endif
  639.